﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Room
{
    public class RCAIMonster : RCAIBase
    {
        public RCAIMonster(RoomCharactor owner)
            : base(owner)
        {
            type = AIType.Monster;
        }
        private float lastTime;

        public Vector3 bornPosition = new Vector3(0, 0, 3);
        public float bornFaceTo = 0f;

        public float wanderRadius = 0f;
        public float pursueRadius = 0f; //追逐最远距离
        public float viewRadius = 0f;   //视野距离

        public float wanderSpeed = 0f;  //巡逻速度
        public float pursueSpeed = 0f;  //追逐速度

        public float rotateSpeed = 0f; //转身速度（每秒/度） 
        public float restTime = 0f;//休息时间

        public string taskId = "";


        public void Init(Dict.DataModel.TableCopyTask data)
        {
            this.bornFaceTo = (float)data.BornAngle;
            this.wanderRadius = (float)data.WanderR;
            this.pursueRadius = (float)data.PursueR;
            this.viewRadius = (float)data.ViewR;
            this.wanderSpeed = (float)data.WanderSpeed;
            this.pursueSpeed = (float)data.PursueSpeed;
            this.rotateSpeed = (float)data.RotateSpeed;
            this.restTime = (float)data.RestTime;
            this.bornPosition = new Vector3((float)data.BornX, 0f, (float)data.BornZ);
            this.taskId = data.TaskId;

            InitFSM();
            InitParticle(data.BornParticleId, data.DeadParticleId);
            if(data.IsBoss==1)
            {
                string path = "particles/" + Dict.Blo.DictParticleBlo.GetCommonParticle("zhiyin_boss").ResourcePath; // "particles/01_general/zhiyin_boss";
                AssetLoadHelper.Instance.LoadAssetAsync(path, CommonMethod.GetAssetNameFromAssetBundleName(path),typeof(GameObject),
                    (asset) =>
                    {
                        GameObject obj = asset as GameObject;
                        if (obj != null)
                        {
                            if (owner == null)
                            {
                                GameObject.Destroy(obj);
                                return;
                            }

                            var heroData = Dict.DictDataManager.Instance.tableHeroDao.GetById(data.HeroId);
                            var height = heroData.Height + 0.2f;

                            obj.SetActive(true);
                            obj.transform.SetParent(owner.transform);
                            obj.transform.localPosition = new Vector3(0, (float)height + 1f, 0);
                            obj.transform.localScale = Vector3.one;
                            obj.transform.localRotation = Quaternion.Euler(Vector3.zero);
                        }
                    });

                owner.extraInfo = "1";
            }
            
        }

        public override void DoStart()
        {
            owner.transform.position = bornPosition;
            SwitchState(MonsterAIState.Born);
        }

        public override void Tick()
        {
            allStates[curState].Tick();
        }

        public bool PlayerInVisualField()
        {
            var monsterPos = owner.transform.position;
            if (owner.charactorManager.room != null)
            {
                var self = owner.charactorManager.GetSelfCharactor();
                if (self == null)
                    return false;
                var playerPos = self.transform.position;

                return Vector3.Distance(playerPos, monsterPos) < viewRadius
                    && Vector3.Distance(monsterPos, bornPosition) < pursueRadius;
            }

            return false;
        }

        #region Particle

        public enum ParticleType
        {
            Born, Dead,
        }
        private float deadParticleDelay;
        private float bornParticleDelay;
        private GameObject deadParticle;
        private GameObject bornParticle;
        private string deathParticlePath;
        private string bornParticlePath;

        public void InitParticle(string bornParticleId, string deadParticleId)
        {
            LoadParticle(deadParticleId,1);
            LoadParticle(bornParticleId,2);
        }

        public void PlayParticle(ParticleType particleType)
        {
            GameObject obj = null;
            float timer = 0;
            if (particleType == ParticleType.Born)
            {
                obj = bornParticle;
                timer = bornParticleDelay;
            }
            else if (particleType == ParticleType.Dead)
            {
                obj = deadParticle;
                timer = deadParticleDelay;
            }

            if (obj != null)
            {
                var transmit = Battle.BattleManager.Instance;
                transmit.StartCoroutine(_PlayParticleHelper(obj, timer));
            }
        }
        IEnumerator _PlayParticleHelper(GameObject obj, float delay)
        {
            if (obj == null) yield break;

            obj.SetActive(true);
            yield return new WaitForSeconds(delay);
            obj.SetActive(false);
            owner.gameObject.SetActive(false);
        }

        float LoadParticle(string particleId, int ei)
        {
            if (!string.IsNullOrEmpty(particleId))
            {
                int id = -1;
                if (int.TryParse(particleId, out id))
                {
                    var particleData = Dict.DictDataManager.Instance.tableParticleDao.GetById(id);
                    if (particleData != null)
                    {
                        var path = "particles/" + particleData.ResourcePath;
                        AssetLoadHelper.Instance.LoadAssetAsync(path, CommonMethod.GetAssetNameFromAssetBundleName(path),typeof(GameObject), (obj) =>
                        {
                            if(owner==null)
                            {
                                GameObject.Destroy(obj);
                                return;
                            }
                            if (obj != null)
                            {
                                GameObject po = obj as GameObject;
                                po.transform.SetParent(owner.transform);
                                po.transform.localScale = Vector3.one;
                                po.transform.localPosition = Vector3.zero;
                                po.name = "particle:" + path;
                                po.SetActive(false);
                                if (ei == 1)
                                {
                                    deathParticlePath = path;
                                    deadParticle = po;
                                    deadParticleDelay = (float)particleData.Duration;
                                }
                                else
                                {
                                    bornParticlePath = path;
                                    bornParticle = po;
                                    bornParticleDelay = (float)particleData.Duration;
                                }
                            }
                            else
                            {
                                Debug.LogError("ERROR:can't load particle at path:" + path);
                            }
                        });
                    }
                }
            }
            
            return 0f;
        }

        #endregion

        #region FSM
        private MonsterAIState curState;
        private Dictionary<MonsterAIState, MonsterAIStateBase> allStates = new Dictionary<MonsterAIState, MonsterAIStateBase>();

        private void InitFSM()
        {
            curState = MonsterAIState.None;

            allStates[MonsterAIState.None] = new MonsterAIStateBase();
            allStates[MonsterAIState.Born] = new MonsterAIStateBorn();
            allStates[MonsterAIState.BackBorn] = new MonsterAIStateBackBorn();
            allStates[MonsterAIState.Dead] = new MonsterAIStateDead();
            allStates[MonsterAIState.DefendSuccess] = new MonsterAIStateDefendSuccess();
            allStates[MonsterAIState.Hold] = new MonsterAIStateHold();
            allStates[MonsterAIState.Move] = new MonsterAIStateMove();
            allStates[MonsterAIState.Pursue] = new MonsterAIStatePursue();
            allStates[MonsterAIState.Rest] = new MonsterAIStateRest();

            foreach (var state in allStates)
            {
                state.Value.controller = this;
            }
        }

        public void SwitchState(MonsterAIState newState)
        {
            allStates[curState].Leave();
            curState = newState;
            allStates[newState].Enter();
        }

        public override void DoStop()
        {
            if(!string.IsNullOrEmpty(bornParticlePath))
            {
                AssetLoadHelper.Instance.UnloadBundle(bornParticlePath);
            }
            if (!string.IsNullOrEmpty(deathParticlePath))
            {
                AssetLoadHelper.Instance.UnloadBundle(deathParticlePath);
            }
        }

        #endregion

        /// <summary>
        /// 停止所有动画
        /// </summary>
        public void StopAnimation()
        {
            allStates[curState].StopAnimation();
        }

        /// <summary>
        /// 重新开始动画
        /// </summary>
        public void RestoreAnimation()
        {
            allStates[curState].RestoreAnimation();
        }
    }

}

